use std::cmp::Ordering;

// Assuming these functions are defined elsewhere in your Rust project
fn int_compare(a: &i32, b: &i32) -> i32 {
    if a < b { -1 } else if a > b { 1 } else { 0 }
}

fn int_equal(a: &i32, b: &i32) -> bool {
    *a == *b
}

// Assuming these functions are defined elsewhere in your Rust project
pub fn pointer_equal(location1: *const (), location2: *const ()) -> bool {
    location1 == location2
}

pub fn pointer_compare(location1: *const (), location2: *const ()) -> Ordering {
    if location1 < location2 {
        Ordering::Less
    } else if location1 > location2 {
        Ordering::Greater
    } else {
        Ordering::Equal
    }
}

// Assuming these functions are defined elsewhere in your Rust project
pub fn string_equal(string1: &str, string2: &str) -> bool {
    string1 == string2
}

pub fn string_compare(string1: &str, string2: &str) -> i32 {
    if string1 < string2 { -1 } else if string1 > string2 { 1 } else { 0 }
}

// Assuming these functions are defined elsewhere in your Rust project
pub fn string_nocase_equal(string1: &str, string2: &str) -> bool {
    string1.to_lowercase() == string2.to_lowercase()
}

pub fn string_nocase_compare(string1: &str, string2: &str) -> i32 {
    let lower1 = string1.to_lowercase();
    let lower2 = string2.to_lowercase();
    if lower1 < lower2 { -1 } else if lower1 > lower2 { 1 } else { 0 }
}

type UnitTestFunction = fn();

fn run_tests(tests: &[Option<UnitTestFunction>]) {
    for test in tests.iter() {
        if let Some(t) = test {
            t();
        } else {
            break;
        }
    }
}

fn main() {
    let tests: [Option<UnitTestFunction>; 8] = [
        Some(test_int_compare),
        Some(test_int_equal),
        Some(test_pointer_compare),
        Some(test_pointer_equal),
        Some(test_string_compare),
        Some(test_string_equal),
        Some(test_string_nocase_compare),
        Some(test_string_nocase_equal),
    ];

    run_tests(&tests);
}

fn test_int_compare() {
    assert_eq!(int_compare(&1, &2), -1);
    assert_eq!(int_compare(&2, &1), 1);
    assert_eq!(int_compare(&1, &1), 0);
}

fn test_int_equal() {
    assert!(int_equal(&1, &1));
    assert!(!int_equal(&1, &2));
}

fn test_pointer_compare() {
    let a = 1;
    let b = 2;
    assert_eq!(pointer_compare(&a as *const _, &b as *const _), Ordering::Less);
    assert_eq!(pointer_compare(&b as *const _, &a as *const _), Ordering::Greater);
    assert_eq!(pointer_compare(&a as *const _, &a as *const _), Ordering::Equal);
}

fn test_pointer_equal() {
    let a = 1;
    let b = 2;
    assert!(pointer_equal(&a as *const _, &a as *const _));
    assert!(!pointer_equal(&a as *const _, &b as *const _));
}

fn test_string_compare() {
    assert_eq!(string_compare("Apple", "Orange"), -1);
    assert_eq!(string_compare("Orange", "Apple"), 1);
    assert_eq!(string_compare("Apple", "Apple"), 0);
}

fn test_string_equal() {
    assert!(string_equal("this is a test string", "this is a test string"));
    assert!(!string_equal("this is a test string", "this is a test string "));
    assert!(!string_equal("this is a test string", "this is a test strin"));
    assert!(!string_equal("this is a test string", "this is a test strinG"));
}

fn test_string_nocase_compare() {
    assert_eq!(string_nocase_compare("Apple", "Orange"), -1);
    assert_eq!(string_nocase_compare("Orange", "Apple"), 1);
    assert_eq!(string_nocase_compare("Apple", "Apple"), 0);
    assert_eq!(string_nocase_compare("Alpha", "bravo"), -1);
    assert_eq!(string_nocase_compare("bravo", "Charlie"), -1);
}

fn test_string_nocase_equal() {
    assert!(string_nocase_equal("this is a test string", "this is a test string"));
    assert!(!string_nocase_equal("this is a test string", "this is a test string "));
    assert!(!string_nocase_equal("this is a test string", "this is a test strin"));
    assert!(string_nocase_equal("this is a test string", "this is a test strinG"));
}
